#include "userMain.h"
#include "userIRreceive.h"

void userIRreceInitFunc(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure; 
    
    /* GPIOA Periph clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
	
    /* Configure PA15 in input pushpull mode */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    EXTI_ClearITPendingBit(EXTI_Line15); 
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource15); 

    EXTI_InitStructure.EXTI_Line = EXTI_Line15 ;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling ;       
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;                          
    EXTI_Init(&EXTI_InitStructure); 
    
    /* Enable and set EXTI4_15 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

uint8_t userIRreceEN = 0;
uint16_t userIrReceTimeout=0;
extern uint8_t uBmaDetectFlag;
void userIrRxStart(void)
{
    userIRreceEN = 1;
    uBmaDetectFlag = 1;
    LED5_IR_Y_ON;
    userIrReceTimeout=0;
    userIRreceInitFunc();
}
void userIrRxEnd(void)
{
    userIRreceEN = 0;
    uBmaDetectFlag = 0;
    EXTI_DeInit();
    LED5_IR_Y_OFF;
}

#define     USER_IR_RECE_CNT_MAX    65535
#define     SIGNAL_CYCLE            26
uint32_t userIRrece_CntNow=0;
uint32_t userIRrece_CntNow2=0;
uint32_t userIRrece_CntPre=0;
int32_t userIRsaveBuff = 0;
uint8_t userIRreceFlag=1;
uint8_t user_ti = 0;
void EXTI4_15_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line15)!=RESET) 
    {  
        if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)==0) ) 
        {
            if(userIRreceFlag==1)
            {
                userIRrece_CntNow = TIM3->CNT; 
                userIRreceFlag = 0;
                userIRreceDealFunc();
            }
            _NOP;
        }
        else
        {
            if(userIRreceFlag==0)
            {
                userIRrece_CntNow2 = TIM3->CNT;  
                userIRrece_CntNow = TIM3->CNT;  
                userIRreceFlag = 1; 
                userIRreceDealFunc();
            }
            _NOP; 
        }
    }
    EXTI_ClearITPendingBit(EXTI_Line15);
}

unsigned char userIRreleaseMark = 0;    
void userIRreleaseTickFunc(void)
{
    if(userIRreleaseMark < 250)
        userIRreleaseMark++;
}

uint8_t userIRdecode[400];
uint16_t userIRdecodeLen;
uint8_t userIRreceStartFlag=0;
static uint16_t userIRrece_i = 0;
uint8_t userIRlearnErrorFlag = 0;
void userIRreceDealFunc(void)
{
    userIRreleaseMark = 0;
    userIRsaveBuff = userIRrece_CntNow - userIRrece_CntPre;
    if(userIRsaveBuff < 0)
    {
        userIRsaveBuff += USER_IR_RECE_CNT_MAX;
    }
    userIRrece_CntPre = userIRrece_CntNow;
    if(userIRreceStartFlag ==0)
    {
        userIRrece_i = 0;
        userIRreceStartFlag = 1;
        userIRlearnErrorFlag = 0;
    }
    else
    {
        userIRsaveBuff = userIRsaveBuff / SIGNAL_CYCLE;
        if(userIRsaveBuff > 0x00FF)
        {
            userIRdecode[userIRrece_i++] = 0;
            userIRdecode[userIRrece_i++] = userIRsaveBuff >> 8;
            userIRdecode[userIRrece_i++] = userIRsaveBuff;
        }
        else
        {
            userIRdecode[userIRrece_i++] = userIRsaveBuff;
        } 
        if(userIRrece_i >=400)
        {
            userIRlearnErrorFlag = 1;
        }
    }
}

#define     IR_RELEASE_CNT      8                                                  
uint8_t userIRlearnFlag = 0;
void userIRreleaseFunc(void)
{
    if(userIrReceTimeout < 1000)
      userIrReceTimeout++;
    if(userIRreleaseMark > IR_RELEASE_CNT)
    {  
         if(userIRreceStartFlag)  
        {
            userIRdecodeLen = userIRrece_i;
            userIRreceStartFlag = 0;
            userIRlearnFlag = 1;
            _NOP;
        } 
    }
}

uint8_t userIRprotect=0;
void userSendLearnCodeIR(void)
{ 
    if(userIRreceEN==0) return ; 
    if((userIrReceTimeout > 500)||(userIRlearnErrorFlag))
    {
        userSendIrLearnTimeoutFunc();
        userIrRxEnd();
        userIRlearnErrorFlag = 0;
        userIRreceStartFlag = 0;
        userIRlearnFlag = 0;
    }   
    else if(userIRlearnFlag)
    {
        userIRlearnFlag = 0;
        if(userIRprotect)
        {
            userIRprotect = 0;
        }
        else
        {
            userSendIrLearnCodeFunc();
            userIrRxEnd();
        }
    }
}

